home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Unca Fenster / Source / Fenster.c next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  5.7 KB  |  204 lines  |  [TEXT/KAHL]

  1. /* Unca Fenster
  2.  *
  3.  * by Timothy Knox & Ed Tecot
  4.  *
  5.  * Written at MacHack 1993
  6.  *
  7.  * Unca Fenster saves the state of all of your open windows in a file called
  8.  * "Fenster Data".  You can rename the file and put it anywhere.  Double-Click
  9.  * on an Unca Fenster file to open all of the windows and restore their state.
  10.  *
  11.  * Well... not really.  The intent is to do all that, but for now, all that
  12.  * is restored is the back-to-front ordering of the windows.  The rest is left
  13.  * as an exercise for the hacker.  In addition, aliases that don't resolve are
  14.  * ignored.  If you want something better, do it youself and submit it next year!
  15.  */
  16.  
  17. #include "Layers.h"
  18. #include "FinderToFSSpec.h"
  19. #include <Aliases.h>
  20. #include <AppleEvents.h>
  21.  
  22. #define rFensCreat    'UNCA'
  23. #define rFensType    'FNST'
  24.  
  25. // Special Undocumented Routines for System Mode
  26. pascal OSErr TurnSystemModeOn(void)  = {0x2F3C, 0x0040, 0x0000, 0xA88F}; 
  27. pascal OSErr TurnSystemModeOff(void) = {0x2F3C, 0x0041, 0x0000, 0xA88F}; 
  28.  
  29. void SendOpenDocToFinder(FSSpec *theCFS, long tId);
  30.  
  31. typedef struct fWinAlias {
  32.     Rect        fRect;
  33.     AliasRecord    fAlias;
  34. }    fWinAlias, *fWinAliasP, **fWinAliasH;
  35.  
  36. typedef struct FinderWRefCon {
  37.     void *dontKnow;
  38.     void *dontKnowEither;
  39.     FinderHandle theFH;
  40. } FinderWRefCon;
  41.  
  42. void CreateFenster(void);
  43. void OpenFenster(AppFile *theFile);
  44.  
  45. main()
  46. {
  47.     short message, count;
  48.  
  49.     MaxApplZone();                    /* expand the heap so code segments load at the top */
  50.     InitGraf((Ptr) &qd.thePort);
  51.  
  52.     /* We can't use the event manager, so get the files the old fashioned way */
  53.     CountAppFiles(&message, &count);
  54.     if (count) {
  55.         short index;
  56.         AppFile theFile;
  57.         for (index = 1; index <= count; index++) {
  58.             GetAppFiles(index, &theFile);
  59.             OpenFenster(&theFile);
  60.             ClrAppFiles(index);
  61.         }
  62.     } else
  63.         CreateFenster();
  64.     ExitToShell();
  65. }
  66.  
  67. /* Go scan the Finder for the appropriate stuff and store it in a file. */
  68. void CreateFenster()
  69. {
  70.     FSSpec theSpec;
  71.     AliasHandle theAliasH;
  72.     Handle rectH;
  73.     long    **fWinCount = (long **) NewHandle(sizeof(long));
  74.     int ref;
  75.     long c = 0;
  76.     OSErr err;
  77.     WindowPeek aFinderWindow = (WindowPeek) GetFirstLayerWindow((LayerPtr) GetFirstLayerWindow(GetFirstLayer()));
  78.  
  79.     HGetVol(theSpec.name, &theSpec.vRefNum, &theSpec.parID);
  80.     BlockMove("\pFenster Data", theSpec.name, 13);
  81.     FSpCreateResFile(&theSpec, rFensCreat, rFensType, 0);
  82.     err = ResError();
  83.     if (!((err == noErr) || (err == dupFNErr)))
  84.         return;    
  85.     ref = FSpOpenResFile(&theSpec, fsRdWrPerm);
  86.     if (ref == -1)
  87.         return;
  88.  
  89.     /* Find all of the windows in the frontmost app, which should be the Finder.
  90.      * Skip the last window, because that's the desktop.
  91.      */
  92.     while (aFinderWindow && aFinderWindow->nextWindow) {
  93.         FinderHandleToFSSpec(((* (FinderWRefCon **) GetWRefCon((WindowPtr) aFinderWindow)))->theFH, &theSpec);
  94.         err = NewAlias(nil, &theSpec, &theAliasH);
  95.         if ((err != noErr) || (theAliasH == nil)) {
  96.             return;
  97.         }
  98.         rectH = NewHandle(sizeof(Rect));
  99.         BlockMove(&aFinderWindow->port.portRect, *rectH, sizeof(Rect));
  100.         AddResource(rectH, 'RECT', ++c, "\p");
  101.         AddResource((Handle) theAliasH, 'alis', c, "\p");
  102.         aFinderWindow = aFinderWindow->nextWindow;
  103.     }
  104.     **fWinCount = c;
  105.     AddResource((Handle) fWinCount, 'CNT!', 0, "\p");
  106.     CloseResFile(ref);
  107. }
  108.  
  109. /* Read the fenster file and open the windows and move them to the proper place */
  110. void OpenFenster(AppFile *theFile)
  111. {
  112.     FSSpec theSpec;
  113.     AliasHandle theAliasH;
  114.     Handle rectH;
  115.     long        **fWinCount;
  116.     Boolean     wasChanged;
  117.     int ref;
  118.     long c;
  119.     OSErr err;
  120.     
  121.     SetVol(nil, theFile->vRefNum);
  122.     ref = OpenResFile (theFile->fName);
  123.     if (ref == -1)
  124.         return;
  125.  
  126.     fWinCount = (long **) GetResource('CNT!', 0);
  127.     err = ResError();
  128.     if (err != noErr)
  129.         return;    
  130.  
  131.     for (c = **fWinCount; c > 0; c--) {
  132.         theAliasH = (AliasHandle) GetResource('alis', c);
  133.         err = ResolveAlias(nil, theAliasH, &theSpec, &wasChanged);
  134.         ReleaseResource((Handle) theAliasH);
  135.         if (err != noErr)
  136.             break;
  137.         rectH = GetResource('RECT', c);
  138.         SendOpenDocToFinder(&theSpec, c);
  139.     }
  140. }
  141.  
  142. #define kAEOpenSelection 'sope'
  143. #define kAEFinderEvents 'FNDR'
  144. #define keySelection 'fsel'
  145. #define keyDirectObject '----'
  146.  
  147. /* send an open msg to Finder for vol,dir,name */
  148. void SendOpenDocToFinder(FSSpec *theCFS, long tId)
  149. {    
  150.     AliasHandle theAlias;
  151.     AppleEvent theMessage,theReply;
  152.     AEAddressDesc theAddress;
  153.     AEDesc theSelAliasList,theSelAliasElement,theParAliasElement;
  154.     int i;
  155.     OSType fndrSig = 'MACS';
  156.  
  157.     TurnSystemModeOn();
  158.  
  159.     AECreateDesc(typeApplSignature,(Ptr)&fndrSig,sizeof(OSType),&theAddress);
  160.  
  161.     /* Create an AppleEvent message */
  162.     AECreateAppleEvent(kAEFinderEvents,kAEOpenSelection,&theAddress,
  163.                         kAutoGenerateReturnID,tId,&theMessage);
  164.  
  165.     /* Create an alias to the parent folder and put it in the msg. */
  166.     NewAlias(0L,theCFS,&theAlias);
  167.  
  168.     /* create an element */
  169.     HLock((Handle) theAlias);
  170.     AECreateDesc(typeAlias,(Ptr)*theAlias,(*theAlias)->aliasSize,&theParAliasElement);
  171.     
  172.     /* now put the element into the message */
  173.     AEPutParamDesc(&theMessage, keyDirectObject,&theParAliasElement);
  174.     DisposHandle((Handle) theAlias);
  175.  
  176.     /* Create a list (the key selection of the message), store the alias in it, and
  177.             put the list in the msg. */
  178.     AECreateList(0L,0,FALSE,&theSelAliasList);
  179.     
  180.     NewAlias(0L,theCFS,&theAlias);
  181.  
  182.     // create the alias descriptor
  183.     HLock((Handle) theAlias);
  184.     AECreateDesc(typeAlias,(Ptr)*theAlias,(*theAlias)->aliasSize,&theSelAliasElement);
  185.  
  186.     /* put the element into the list */
  187.     AEPutDesc(&theSelAliasList,0,&theSelAliasElement);
  188.     DisposHandle((Handle) theAlias);
  189.  
  190.     /* now put the list into the message */
  191.     AEPutParamDesc(&theMessage, keySelection,&theSelAliasList);
  192.  
  193.     /* Send it off. */
  194.     AESend(&theMessage,0L, kAENoReply, kAENormalPriority,1000,0L,0L);
  195.  
  196.     AEDisposeDesc(&theAddress);
  197.     AEDisposeDesc(&theMessage);
  198.     AEDisposeDesc(&theSelAliasElement);
  199.     AEDisposeDesc(&theSelAliasList);
  200.     AEDisposeDesc(&theParAliasElement);
  201.  
  202.     TurnSystemModeOff();
  203. }
  204.